// 高级类型
fn main() {
    // 1.类型别名
    // 使用type关键字创建
    type Ha = i32;
    let a: i32 = 5;
    let b: Ha = 5;
    // 2. never类型, 有一个名为!的特殊类型(todo)
    // 行话叫做“空类型”, 因为它在不返回的函数中充当返回类型
    // 不返回值的函数又被称作“发散函数”
    // fn bar() -> ! {
    // }
    let guess = "32";
    // loop {// loop 无限循环, 直到遇到break;
    //     // match必须返回相同的值, 而continue就是never类型, 而never无法提供可供返回的值, 所以采用分支1, u32类型(todo)
    //     let guess:u32 = match guess.trim().parse() {
    //         Ok(num) => num,
    //         Err(_) => continue, 
    //     };
    // };
    // 再来看:
    // 以下表达式返回的就是never类型, 即永远不会返回值
    // loop {
    //     println!("and ever");
    // }
    // 3. 动态大小的类型
    // Dynamically Sized Types, DST, 编写代码时使用只有在运行时才能确定大小的值
    // 以下代码肯定无法正常工作, 因为rust需要在编译时知道值内存的大小
    // let s1:str = "hello";
    // let s2:str = "hi";
    // &str存的是str的地址和长度
    // 掘金: 在rust中, 引用类型和trait对象都是动态大小类型
    trait Shape {
        fn area(&self) -> f64;
    }
    struct Circle {
        radius: f64,
    }
    impl Shape for Circle {
        fn area(&self) -> f64 {
            self.radius * self.radius * std::f64::consts::PI
        }
    }
    struct Rectangle {
        width: f64,
        height: f64
    }
    impl Shape for Rectangle {
        fn area(&self) -> f64 {
            self.width * self.height
        }
    }
    let circle = Circle {radius: 10.12};
    let shape: &dyn Shape = &circle; // 这里就是用trait对象(&dyn Shape)来引用具体的值;
    println!("area is {}", circle.area());

    // 咱利用动态大小类型实现多态
    let rectangle = Rectangle {width: 12.0, height: 12.0};
    let circle2 = Circle {radius: 10.0};
    let shape_list:Vec<&dyn Shape> = vec![&rectangle, &circle2];
    for item in shape_list {
        println!("area:{}", item.area()); // 充分利用多态
    }
    // 4. Sized Trait, Sized Trait 是 Rust 中的一个特殊的 trait ，(todo)
    // 用于标识类型是否在编译期已知大小。所有类型默认都是 Sized 的，除非使用特殊语法将其标识为不具有确定大小的动态大小类型。
    // 不确定的, 可以使用?Sized来标注
    // 正确示例：使用动态大小类型作为泛型参数
    // fn process_data<T: ?Sized>(data: &[T]) {
    //     // 处理数据
    // }
    // let vec_data:Vec<i32> = vec![1, 2, 3, 4, 5];
    // process_data<i32>(&vec_data);
    // fn process_data<T: ?Sized>(data: &[T]) {}


}
